package winOrDie.GameEngine.RT;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.EventObject;

public class WoD_Event extends EventObject implements Comparable<WoD_Event> {
	
	/*
	 * Movement data
	 */
	private int type = -1;
	private long Ts = 0L;
	private int estadoPartida = 0; //0 -> empezada, 1 -> princesa rescatada de la caseta, 2 -> capitan & princesa ganan, 3 -> piratas ganan
	private int coordY = 0;
	private int coordX = 0;
	private int coordY_old = 0;
	private int coordX_old = 0;
	private int mirando = 0;
	private int Player = 0;
	
	/*
	 * Game information data
	 */
	private String client_Host = null;
	private int voice_port = 0;
	private String sntp_serverName = null;
	
	/*
	 * Tipos de evento
	 */
	public static final int MOVE = 0;
	
	public static final int BALL = 1;
	public static final int SPACE_BAR = 2;
	
	public static final int NEW_PLAYER = 3;
	public static final int GAME_DATA = 4;
	
	
	
	public long getTs() {
		return Ts;
	}

	public void setTs(long ts) {
		Ts = ts;
	}
	
	/**
	 * 0 -> empezada, 1 -> princesa rescatada de la caseta, 2 -> capitan & princesa ganan, 3 -> piratas ganan
	 * @return
	 */
	public int getEstadoPartida() {
		return estadoPartida;
	}

	/**
	 * 0 -> empezada, 1 -> princesa rescatada de la caseta, 2 -> capitan & princesa ganan, 3 -> piratas ganan
	 * @param estado
	 */
	public void setEstadoPartida(int estado) {
		this.estadoPartida = estado;
	}

	public int getCoordY() {
		return coordY;
	}

	public void setCoordY(int coordY) {
		this.coordY = coordY;
	}
	
	public void setCoordY_old(int coordY_old) {
		this.coordY_old = coordY_old;
	}
	
	public int getCoordX() {
		return coordX;
	}

	public int getCoordY_old() {
		return coordY_old;
	}

	public int getCoordX_old() {
		return coordX_old;
	}

	public void setCoordX(int coordX) {
		this.coordX = coordX;
	}
	
	public void setCoordX_old(int coordX_old) {
		this.coordX_old = coordX_old;
	}
	
	public void setMirando(int mirando) {
		this.mirando = mirando;
	}

	public int getMirando() {
		return mirando;
	}

	public int getType() {
		return type;
	}

	public int getPlayer() {
		return Player;
	}

	public void setPlayer(int player) {
		Player = player;
	}

	public String getClient_Host() {
		return client_Host;
	}

	public void setClient_Host(String clientHost) {
		client_Host = clientHost;
	}

	public int getVoice_port() {
		return voice_port;
	}

	public void setVoice_port(int voicePort) {
		voice_port = voicePort;
	}

	public String getSntp_serverName() {
		return sntp_serverName;
	}

	public void setSntp_serverName(String sntpServerName) {
		sntp_serverName = sntpServerName;
	}

	/**
	 * 
	 * @param source
	 * @param type
	 */
	public WoD_Event(Object source, int type) {
		super(source);
		this.type = type;
	}
	
	@Override
	public int compareTo(WoD_Event o) {
		if (Ts < o.getTs())
		{
			return -1;
		}
		else if (Ts > o.getTs())
		{
			return 1;
		}
		
		return 0;
	}

	
	public byte[] get_BytesArray() throws IOException
	{
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
		
		dataOutputStream.writeByte(type);
		
		switch (type) {
		
		/**
		 * Move event
		 */
		case MOVE:
			dataOutputStream.writeLong(Ts);
			dataOutputStream.writeByte(estadoPartida);
			dataOutputStream.writeByte(Player);
			dataOutputStream.writeInt(coordX);
			dataOutputStream.writeInt(coordY);
			dataOutputStream.writeInt(coordX_old);
			dataOutputStream.writeInt(coordY_old);
			dataOutputStream.writeInt(mirando);
			break;

		/** 
		 * Ball movement event
		 */
		case BALL:
			dataOutputStream.writeLong(Ts);
			dataOutputStream.writeByte(Player);
			dataOutputStream.writeInt(coordX);
			dataOutputStream.writeInt(coordY);
			break;
		
		/**
		 * Space bar event
		 */
		case SPACE_BAR:
			dataOutputStream.writeLong(Ts);
			dataOutputStream.writeByte(Player);
			break;
		
		/**
		 * New player event
		 */
		case NEW_PLAYER:
			dataOutputStream.writeInt(voice_port);
			dataOutputStream.writeUTF(client_Host);
			break;
			
		/**
		 * Game Data event
		 */
		case GAME_DATA:
			dataOutputStream.writeInt(voice_port);
			dataOutputStream.writeUTF(sntp_serverName);
			break;
			
		default:
			break;
		}
		
		/*
		// Old method
		dataOutputStream.writeLong(Ts);
		dataOutputStream.writeByte(Player);
		dataOutputStream.writeInt(coordX);
		dataOutputStream.writeInt(coordY);
		*/
		
		
		return byteArrayOutputStream.toByteArray();
	}
	
	public static WoD_Event get_Pong_Event_From_ByteArray(byte[] buffer) throws IOException
	{
		ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer);
		DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);
		
		int type = dataInputStream.readByte();
		
		WoD_Event event = new WoD_Event("a", type);
		
		switch (type) {
		case MOVE:
			event.setTs(dataInputStream.readLong());
			event.setEstadoPartida(dataInputStream.readByte());
			event.setPlayer(dataInputStream.readByte());
			event.setCoordX(dataInputStream.readInt());
			event.setCoordY(dataInputStream.readInt());
			event.setCoordX_old(dataInputStream.readInt());
			event.setCoordY_old(dataInputStream.readInt());
			event.setMirando(dataInputStream.readInt());
			break;
		
		case BALL:
			event.setTs(dataInputStream.readLong());
			event.setPlayer(dataInputStream.readByte());
			event.setCoordX(dataInputStream.readInt());
			event.setCoordY(dataInputStream.readInt());	
			break;
		
		case SPACE_BAR:
			event.setTs(dataInputStream.readLong());
			event.setPlayer(dataInputStream.readByte());
			break;
			
		case NEW_PLAYER:
			event.setVoice_port(dataInputStream.readInt());
			event.setClient_Host(dataInputStream.readUTF());
			break;
			
		case GAME_DATA:
			event.setVoice_port(dataInputStream.readInt());
			event.setSntp_serverName(dataInputStream.readUTF());
			break;
			
		default:
			break;
		}
		
		
		
		/*
		// Old method
		event.setTs(dataInputStream.readLong());
		event.setPlayer(dataInputStream.readByte());
		event.setCoordX(dataInputStream.readInt());
		event.setCoordY(dataInputStream.readInt());		
		 */
		
		return event;
	}
	
}
